//////////////////////////////////////////////////////////////////////
//
//	Copyright 2010-2011 Rogo's Team. All Rights Reserved
//
//////////////////////////////////////////////////////////////////////
package com.rogo.mvc.core
{
	import com.rogo.mvc.interfaces.ICommand;
	import com.rogo.mvc.interfaces.IController;
	import com.rogo.mvc.interfaces.INotification;
	import com.rogo.mvc.interfaces.IView;
	import com.rogo.mvc.sub.observer.Observer;
	
	import flash.utils.Dictionary;
	
	/**
	 * 控制器类, 单例
	 * 
	 * <p>实现IController接口, 负责命令的注册 执行</p>
	 *  
	 * @author coco
	 */	
	public class Controller implements IController
	{
		public function Controller()
		{
			super();
			
			init();
		}
		
		//--------------------------------------------------------------------------
		//
		//  Properties
		//
		//--------------------------------------------------------------------------
		
		private static var instance:IController;
		private var view:IView;
		private var commandMap:Dictionary;
		
		//--------------------------------------------------------------------------
		//
		//  Methods
		//
		//--------------------------------------------------------------------------
		
		public static function getInstance():IController
		{
			if (!instance) instance = new Controller();
			return instance;
		}
		
		private function init():void
		{
			commandMap = new Dictionary();
			view = View.getInstance();
		}
		
		//--------------------------------------------------------------------------
		//
		//  注册命令
		//
		//--------------------------------------------------------------------------
		
		/**
		 * 注册一条命令
		 * 
		 * @param notificationName  通知名称
		 * @param commandClassRef   映射命令类
		 */		
		public function registerCommand(notificationName:String, commandClassRef:Class):void
		{
			if (!commandMap[notificationName])
			{
				view.registerObserver(notificationName, new Observer(executeCommand, this));
			}
			commandMap[notificationName] = commandClassRef;
		}
		
		/**
		 * 删除命令
		 * 
		 * @param notificationName
		 */		
		public function removeCommand(notificationName:String):void
		{
			if (hasCommand(notificationName))
			{
				view.removeObserver(notificationName, this);
				
				delete commandMap[notificationName];
			}
		}
		
		/**
		 * 执行命令
		 * 
		 * @param notification 通知对象
		 */		
		public function executeCommand(notification:INotification):void
		{
			var commandClassRef:Class = commandMap[notification.name];
			
			if (!commandClassRef) return;
			
			var command:ICommand = new commandClassRef();
			command.execute(notification);
		}
		
		/**
		 * 命令是否已经存在
		 * 
		 * @param notificationName
		 * @return 
		 */		
		public function hasCommand(notificationName:String):Boolean
		{
			return commandMap[notificationName] != null;
		}
	}
}